﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Drawing;
using System.Windows.Forms;

namespace Echinus
{
    #region MachineInfo
    public abstract class MachineInfo
    {
        public MachineInfo(string ip, string user, string pwd)
        {
            ConnectionOptions connOption = new ConnectionOptions();
            connOption.Username = user;
            connOption.Password = pwd;
            
            magScope = new ManagementScope();
            magScope.Path = new ManagementPath("\\\\" + ip + "\\root\\cimv2");
            magScope.Options = connOption;
            TimeSpan timeout = new TimeSpan(1000);
            magScope.Options.Timeout = timeout;
            hasGetInfo = false;
            this.ip = ip;
        }

        public MachineInfo(string ip)
        {
            magScope = new ManagementScope();
            magScope.Path = new ManagementPath("\\\\" + ip + "\\root\\cimv2");
            TimeSpan timeout = new TimeSpan(1000);
            magScope.Options.Timeout = timeout;
            hasGetInfo = false;
            this.ip = ip;
        }

        public MachineInfo()
        {
            hasGetInfo = false;
        }

        protected string Obj2Str(object obj)
        {
            if (obj == null)
                return "";
            else
                return obj.ToString().Trim();
        }

        public abstract void GetInfo( bool refresh );
        public abstract void Save( System.Data.Common.DbConnection conn, System.Data.Common.DbCommand commd);    //保存信息到数据库中 


        //public string infoName     //信息的名称
        //{ get;}

        public bool hasGetInfo{get;set;}
        public string ip;
        protected ManagementScope magScope = null;

    }

    #endregion

    #region OSInfo
    public class OSInfo : MachineInfo
    {
        public OSInfo(string ip,string user,string pwd)
            : base(ip,user,pwd)
        { 
        }

        public OSInfo(string ip)
            : base(ip)
        { }

        public OSInfo(string ip,string version, string countryCode, string csdversion, string caption, string csname)
        {
            Version = version;
            CountryCode = countryCode;
            CSDVersion = csdversion;
            CSName = csname;
            Caption = caption;
            hasGetInfo = true;
            this.ip = ip;
        }

        public string Version{get;set;}
        public string CountryCode{get;set;}
        public string CSDVersion{get;set;}
        public string Caption{get;set;}
        public string CSName { get; set; }

        public override void GetInfo(bool refresh)
        {
            if (refresh || !hasGetInfo)
            {
                //magScope.Connect();

                //注意： WMI返回值的顺序是一定的，与select之后的属性顺序无关。
                ObjectQuery query = new ObjectQuery("SELECT Version,CountryCode,CSDVersion,Caption,CSName FROM Win32_OperatingSystem ");

                ManagementObjectSearcher Searcher = new ManagementObjectSearcher(magScope, query);

                foreach (ManagementObject mo in Searcher.Get())
                {
                    Version = Obj2Str(mo["Version"]);
                    CountryCode = Obj2Str(mo["CountryCode"]);
                    CSDVersion = Obj2Str(mo["CSDVersion"]);
                    Caption = Obj2Str(mo["Caption"]);
                    CSName = Obj2Str(mo["CSName"]);
                }

                hasGetInfo = true;
            }
        }

        public override void Save(System.Data.Common.DbConnection conn, System.Data.Common.DbCommand commd )
        {
            if (!hasGetInfo)
                GetInfo( true );
            else
            {
                //保存到数据库中。
                
                commd.CommandText = "UPDATE basicinfo SET oscaption='" + Caption + "',oscountrycode='" + CountryCode +
                    "',oscsdversion = '" + CSDVersion + "',osversion='" + Version + "',hostname='" + CSName + "' WHERE ip='" + ip + "'";
                commd.CommandType = System.Data.CommandType.Text;
                commd.Connection = conn;

                try
                {
                    conn.Open();
                    commd.ExecuteNonQuery();

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    if (conn.State != System.Data.ConnectionState.Closed)
                    {
                        conn.Close();
                    }
                }
            }
        }
    }

    #endregion

    #region CPUInfo
    class CPUInfo : MachineInfo
    {
        public CPUInfo(string ip,string user,string pwd)
            : base(ip,user,pwd)
        { 
        }

        public CPUInfo(string ip)
            : base(ip)
        { }

        public CPUInfo(string ip,string caption, string currcntClock, string maxClock, string manufacturer, string name, string pid, string coreNo)
        {
            Caption = caption;
            CurrentClockSpeed = currcntClock;
            Manufacturer = manufacturer;
            MaxClockSpeed = maxClock;
            Name = name;
            ProcessorId = pid;
            NumberOfCores = coreNo;
            hasGetInfo = true;
            this.ip = ip;            
        }

        public string Caption{get;set;}
        public string CurrentClockSpeed{get;set;}
        public string Manufacturer{get;set;}
        public string MaxClockSpeed{get;set;}
        public string Name { get; set; }
        public string ProcessorId{get;set;}
        public string NumberOfCores{get;set;}


        public override void GetInfo(bool refresh)
        {
            if (refresh || !hasGetInfo)
            {
                //magScope.Connect();

                //注意： WMI返回值的顺序是一定的，与select之后的属性顺序无关。(按alpha表顺序返回)

                ObjectQuery query = new ObjectQuery("SELECT Caption,CurrentClockSpeed,Manufacturer,MaxClockSpeed,Name,NumberOfCores,ProcessorId FROM Win32_Processor ");
               
                ManagementObjectSearcher Searcher = new ManagementObjectSearcher(magScope, query);
                
                try
                {
                    foreach (ManagementObject mo in Searcher.Get())
                    {

                        Caption = Obj2Str(mo["Caption"]);
                        CurrentClockSpeed = Obj2Str(mo["CurrentClockSpeed"]);
                        Manufacturer = Obj2Str(mo["Manufacturer"]);
                        MaxClockSpeed = Obj2Str(mo["MaxClockSpeed"]);
                        Name = Obj2Str(mo["Name"]);
                        ProcessorId = Obj2Str(mo["ProcessorId"]);

                        NumberOfCores = Obj2Str(mo["NumberOfCores"]);


                    }
                }
                catch
                {
                    query.QueryString = "SELECT Caption,CurrentClockSpeed,Manufacturer,MaxClockSpeed,Name,ProcessorId FROM Win32_Processor ";
                    Searcher.Query = query; //更新query

                    foreach (ManagementObject mo in Searcher.Get())
                    {
                        Caption = Obj2Str(mo["Caption"]);
                        CurrentClockSpeed = Obj2Str(mo["CurrentClockSpeed"]);
                        Manufacturer = Obj2Str(mo["Manufacturer"]);
                        MaxClockSpeed = Obj2Str(mo["MaxClockSpeed"]);
                        Name = Obj2Str(mo["Name"]);
                        ProcessorId = Obj2Str(mo["ProcessorId"]);

                        NumberOfCores = "N/A";

                    }
                }

                hasGetInfo = true;
            }
        }

        public override void Save(System.Data.Common.DbConnection conn, System.Data.Common.DbCommand commd )
        {
            if (!hasGetInfo)
                GetInfo(true);
            else
            {
                //保存到数据库中。

                commd.CommandText = "UPDATE basicinfo SET cpucaption='" + Caption + "',cpucurrentclock='" + CurrentClockSpeed +
                    "',cpumanufacturer = '" + Manufacturer + "',cpumaxclock='" + MaxClockSpeed + "',cpuname='" + Name + 
                    "',cpunumberofcores='" + NumberOfCores + "',cpuprocessorid='" + ProcessorId + "' WHERE ip='" + ip + "'";
                commd.CommandType = System.Data.CommandType.Text;
                commd.Connection = conn;

                try
                {
                    conn.Open();
                    commd.ExecuteNonQuery();

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    if (conn.State != System.Data.ConnectionState.Closed)
                    {
                        conn.Close();
                    }
                }
            }
        }
    }

    #endregion

    class RuntimeInfo : MachineInfo
    {
        public RuntimeInfo(string ip,string user,string pwd)
            : base(ip,user,pwd)
        {
            //cpuInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetCPUInfoHelper));
            //osInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetOSInfoHelper));
        }

        public RuntimeInfo(string ip)
            : base(ip)
        {
            //cpuInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetCPUInfoHelper));
            //osInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetOSInfoHelper));
        }

        public override void GetInfo(bool refresh)
        {
            if (refresh || !hasGetInfo)
            {
                //magScope.Connect();
                
                    cpuInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetCPUInfoHelper));
                
                    osInfoThread = new System.Threading.Thread(new System.Threading.ThreadStart(GetOSInfoHelper));
                
                cpuInfoThread.Start();

                osInfoThread.Start();
            }
        }

        public void StopGetInfo()
        {
            cpuInfoThread.Abort();
            osInfoThread.Abort();
        }


        private void GetCPUInfoHelper()
        {
            //注意： WMI返回值的顺序是一定的，与select之后的属性顺序无关。
            ObjectQuery query = new ObjectQuery("SELECT LoadPercentage FROM Win32_Processor");

            ManagementObjectSearcher Searcher = new ManagementObjectSearcher(magScope, query);
            while (true)
            {
                foreach (ManagementObject mo in Searcher.Get())
                {
                    CPULoadPercentage = Int32.Parse(mo["LoadPercentage"].ToString());
                }

                hasGetInfo = true;
                System.Threading.Thread.Sleep(RefreshInterval);
            }
           
            //System.Threading.Thread.Sleep(RefreshInterval);
           
        }

        private void GetOSInfoHelper()
        {
            ObjectQuery query = new ObjectQuery("SELECT FreePhysicalMemory,FreeVirtualMemory,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem"); 
            ManagementObjectSearcher Searcher = new ManagementObjectSearcher(magScope, query);
            while (true)
            {
                foreach (ManagementObject mo in Searcher.Get())
                {
                    FreePhysicalMemory = Int64.Parse(mo["FreePhysicalMemory"].ToString());
                    FreeVirtualMemory = Int64.Parse(mo["FreeVirtualMemory"].ToString());
                    TotalVirtualMemorySize = Int64.Parse(mo["TotalVirtualMemorySize"].ToString());
                    TotalVisibleMemorySize = Int64.Parse(mo["TotalVisibleMemorySize"].ToString());

                }
                System.Threading.Thread.Sleep(RefreshInterval);
            }
        }

        public override void Save(System.Data.Common.DbConnection conn, System.Data.Common.DbCommand commd)
        {
            throw new NotImplementedException();
        }

        private System.Threading.Thread cpuInfoThread;
        private System.Threading.Thread osInfoThread;

        public int RefreshInterval = 500;

        public int CPULoadPercentage { get; set; }
        public Int64 FreePhysicalMemory { get; set; }
        public Int64 FreeVirtualMemory { get; set; }
        public Int64 TotalVisibleMemorySize { get; set; }
        public Int64 TotalVirtualMemorySize { get; set; }
        public int VirtualMemUsage { get; private set; }
        public int PhysicalMenUsage { get; private set; }
    }
}
